#!/usr/bin/python
# -- coding: utf-8 --
# This script can be freely used under the terms of BSD license
# Author provides no guarantee about this software
# Copyright: Jakub Lucký 2007

#importy
import os.path
import shutil
import os
import sys
import re 
from optparse import OptionParser

#funkce pro pouze verbose výpis
def verbose(text):
    if options.verbose:
        print text

#Funkce na výpis pouze pokud není quiet
def notquiet(text):
    if not options.quiet:
        print text




#definice objektu parser, verze programu a popisu v --help
parser = OptionParser(usage="%prog [-sqnov] playlist destination/", version="%prog 0.1")

#Parametr na přepsání/nepřepsání souborů při kopírování
parser.add_option("-n", "--no-overwrite", action="store_true", dest="nooverwrite", help="Automatically denies ovewriting [default: %default]")
parser.add_option("-o", "--overwrite", action="store_true", dest="overwrite", help="Automatically overwrites existing files. [default: %default]")

#parametr pro minimum sdělovaných informací
parser.add_option("-q", "--quiet", action="store_true", dest="quiet", help="suppres any unneeded informations  [default: %default]")

# parametr na srovnání souborů podle playlistu
parser.add_option("-s", "--sort", action="store_true", dest="sort", help="Sort (Sort and rename files in same order as in playlist). [default: %default]")

# parametr pro víc informací pro uživatele
parser.add_option("-v", "--verbose", action="store_true", dest="verbose", help="Print additional informations while running. [default: %default]")


#načtení argumentů do options, argumentů do args
(options, args) = parser.parse_args()

#kontrola počtu argumentů, když nejsou dva, uživatel to zkonil a končí
if  len(args) != 2:
    print "Error! Invalid arguments! "
    sys.exit(1)

#Pokud je uživatel dement a chce verbose a quiet zároven
if options.verbose and options.quiet:
    print "Error! Can't be verbose and quiet at the same time!!"
    sys.exit(1)
    
#uložení parametrů do proměnných
playlist = os.path.abspath(args[0])
destination = os.path.abspath(args [1])

# Verbose informace
verbose("Using playlist: "+playlist)
verbose("Copying destination: "+destination)
verbose("---------------------------------------------------------------------------- \r\n")
    
  
#test jestli existuje playlist
if not os.path.isfile(playlist):
    print "zadaná cesta:" + playlist + " neexistuje!"
    sys.exit(1)

#test jestli existuje císlo
if not os.path.isdir(destination):
    print "zadaná cesta:" + destination + " neexistuje!"
    sys.exit(1)

#načtení playlistu do pole rows
f = open(playlist)
rows = f.readlines()

#změna Working Directory aby seděli relativní cesty v playlistu
work_dir = os.path.dirname(playlist)
os.chdir(work_dir)

#vyrábíme pole pro uložení fileů
files=[]

#cyklus pro filtrovaní playlistu
for row in rows:
    #kontrola jestli řádek není komentář
    if re.match(r"^[^#].*$" ,row): #
        
        #kontrola jestli má řádek na konci \r\n jako konec řádku
        if re.match(r"^.*\r\n",row): 
            i = len(row) - 2 #zajistíme proměnnou i pro zkrácení toho řádku o \r\n
            row = row[0:i] #zkrátíme row 
        # stejně jako kontrola pro \r\n (jistící kontrola pro editory z jiných OS)     
        if re.match(r"^.*\r",row) or re.match(r"^.*\n",row): 
            i = len(row) - 1 
            row = row[0:i] 
        
        #pokud ten soubor skutečně existuje, uložíme ho
        if os.path.isfile(row):
            files.append(os.path.abspath(row))
        #soubor neexistuje, sdělíme to uživateli
        else:
            #sdělíme pokud uživatel nechce ticho
            notquiet("File " + os.path.abspath(row) + " doesn't exist, therefore can't be copied")

#zkontrolujeme, je-li vůbec co kopírovat
if len(files) == 0:
    notquiet("No files to copy")
    sys.exit(0)
                

#zjištění řádu počtu kopírovaných souborů kvůli sortování    
if options.sort:
    curr_length=len(files)
    #je jich min jak 10, nemá cenu to řešit
    if curr_length < 10:
        order=0
    #Je jich víc jak deset, budeme to řešit, default je jedna
    else:
        order=1
        #provede se, jen když jich bude víc jak sto
        while not curr_length/10 < 10 and curr_length/10 >= 1:
            order += 1
            curr_length = curr_length/10
    #vytvoření pole se sesortovanými názvy
    sorted_files=[]
    i = 1 #i je číslování 
    #projde pole files, zkonvertuje 
    for old_path in files:
        #Edituje starou cestu na novou
        new_path = os.path.dirname(old_path) + "/" + "0"*(order - (len(str(i))-1)) + str(i) + "_" + os.path.basename(old_path)
        #zapíše novou cestu do pole
        sorted_files.append(new_path)
        i +=1
        #proměnná kvůli určení fileu podle indexu
    sort_index = 0
 
 
#definice proměnné kvůli sort režimu
if options.verbose:
    old_wd = ""

    

#hlavní kopírovací cyklus
for file in files:

    #verbose info o adresáři
    if options.verbose:
        #kontrolujeme změnu kopírovacího adresáře (pokud je jiný, vypíšeme)
        if not old_wd == os.path.dirname(file):
            verbose("Currently copying from: "+ os.path.dirname(file) + "\r\n")
            old_wd = os.path.dirname(file)
    
    #proměnná kvůli kontrole existence (ochrana proti přepisu)
    if options.sort:
        copy_loc = sorted_files[sort_index]
    else:
        copy_loc = destination +"/"+ os.path.basename(file)
    
    #Soubor kam chceme kopírovat již existuje
    
    if os.path.exists(copy_loc):
        #uživatel zvolil parametr nepřepisovat
        if options.nooverwrite:
            notquiet("File: " + file + "  not copied! Name collision")
            continue
        #uživatel nezvolil parametr přepisovat, budeme se ptát
        elif not options.overwrite:
        #cyklus při kterém razantně čekáme odpověd
            while 1:
                if not options.sort:
                    answer = raw_input("File "+file +" exist in copying location! Do you like to overwrite it? [Y]es, [N]o or [R]ename ")
                else:
                    answer = raw_input("File "+os.path.basename(copy_loc) +" exist in copying location! Do you like to overwrite it? [Y]es, [N]o or [R]ename")
                #kontrola správnosti odpovědi
                if not answer in 'yYnNrR':
                    print "Wrong Answer! Repeat!"
                    continue
                #odpověděl správně, konec cyklu
                else: break
            
            #chce to tam ale nechce přepisovat, tak přejmenujeme
            if answer and answer in "rR":
                tmp_namer = 1
                while 1:
                    copy_loc = copy_loc + "_" + str(tmp_namer)
                    if not os.path.exists(os.path.basename(copy_loc)):
                        verbose("Filename changed to: " + os.path.basename(copy_loc))
                        break
                    tmp_namer += 1
            elif not (answer and answer in 'yY'):
                notquiet("File: " + file + " not copied! Name collision!!")
                continue
            
            #odpověděl ano
            else:
                notquiet("Overwritting file " + copy_loc + " !!")
        
        #zvolil přepisovací parametr
        if options.overwrite:
            notquiet("Overwritting file " + copy_loc + " !!")
        if options.sort:
            sort_index += 1
    #pokusíme se o přepis    
    try:
        shutil.copy(file,destination + "/" + os.path.basename(copy_loc))
        #verbose info navíc
        verbose("File: " + os.path.basename(file) + " ------- Succesfully copied!")
    except IOError:
        print "Error in copying file: "+ file 
        
    
    


